home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 2000 #5
/
Amiga Plus CD - 2000 - No. 5.iso
/
Tools
/
Dev
/
FPSE_src
/
sio.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-01-01
|
4KB
|
192 lines
/*
SIO -- PSX serial driver
========================
Written by LDChen
*/
#include "fpse.h"
SIO_Type Sio0;
SIO_Type Sio1;
static FifoTable[4] = { 1, 2, 4, 8 };
static void dummy() {}
int sio_init()
{
memset(&Sio0,0,sizeof(Sio0));
memset(&Sio1,0,sizeof(Sio1));
Sio0.Status = Sio1.Status = TX_EMPTY | TX_RDY;
Sio0.Mode = Sio1.Mode = PRESCALER1 | BYTE8BIT | STOP1BIT;
Sio0.Baud = Sio1.Baud = SIOBAUDCLOCK/2400;
Sio0.FifoSize = Sio1.FifoSize = 1;
Sio0.IrqLevel = INT_SIO0;
Sio1.IrqLevel = INT_SIO1;
Sio0.IrqSrc = SIO_IRQ_IMM;
Sio1.IrqSrc = SIO_IRQ_IMM;
// Configure SIO0
if (PAD_Init(&Sio0) == FPSE_ERR)
{
printf("Failed GAMEPAD initialization.\n");
return FPSE_ERR;
}
Sio0.UpdateStatus = PAD_UpdateStatus;
Sio0.WriteData = PAD_WriteData;
// Configure SIO1
if (useserial)
{
if (RS232_Init(&Sio1) == FPSE_ERR)
{
printf("Failed Rs232 initialization.\n");
return FPSE_ERR;
}
Sio1.UpdateStatus = RS232_UpdateStatus;
Sio1.WriteData = RS232_WriteData;
} else {
Sio1.UpdateStatus = dummy;
Sio1.WriteData = dummy;
}
return FPSE_OK;
}
void sio_control_write(SIO_Type *sio, int data)
{
sio->Ctrl.Control16 = data & ~ERROR_RESET;
sio->FifoSize = FifoTable[sio->Ctrl.Control8.Irq & 3];
if (data & ERROR_RESET) sio->Status &= ~SIO_IRQ;
sio->UpdateStatus(sio);
}
void sio_baud_write(SIO_Type *sio, int data)
{
sio->Baud = data;
sio->UpdateStatus(sio);
}
void sio_mode_write(SIO_Type *sio, int data)
{
sio->Mode = data;
sio->UpdateStatus(sio);
}
int sio_readdata8 (SIO_Type *sio)
{
int ret = 0;
if (sio->RxNum)
{
ret = sio->RxBuf[sio->RxStart];
if (++sio->RxStart >= MAXIOBUF)
sio->RxStart = 0;
if (!(--sio->RxNum))
sio->Status &= ~RX_RDY;
sio->Status &= ~RX_OVERRUN;
}
return ret;
}
int sio_readdata16(SIO_Type *sio)
{
return (sio_readdata8(sio)) |
(sio_readdata8(sio) << 8);
}
int sio_readdata32(SIO_Type *sio)
{
return (sio_readdata8(sio)) |
(sio_readdata8(sio) << 8) |
(sio_readdata8(sio) << 16) |
(sio_readdata8(sio) << 24);
}
void sio_writedata8(SIO_Type *sio, int data)
{
sio->Status &= ~TX_EMPTY;
sio->TxBuf[sio->TxNum] = (UINT8)data;
if (++sio->TxNum >= sio->FifoSize)
{
sio->Status &= ~TX_RDY;
if (sio->Ctrl.Control8.Line & TxENABLE)
{
sio->WriteData(sio);
sio->TxNum = 0;
sio->Status |= (TX_RDY | TX_EMPTY);
if (sio->Ctrl.Control8.Irq & TxIRQ)
{
Irq_Pulse |= sio->IrqLevel;
sio->Status |= SIO_IRQ;
}
}
}
}
void sio_writedata16(SIO_Type *sio, int data)
{
sio_writedata8(sio,data);
sio_writedata8(sio,data >> 8);
}
void sio_writedata32(SIO_Type *sio, int data)
{
sio_writedata8(sio,data);
sio_writedata8(sio,data >> 8);
sio_writedata8(sio,data >> 16);
sio_writedata8(sio,data >> 24);
}
int sio_async(SIO_Type *sio, char *buf, int len)
{
int n,k;
n = sio->FifoSize - sio->RxNum;
if (len > n)
{
len = n;
sio->Status |= RX_OVERRUN;
}
if (len)
{
k = sio->RxEnd;
for (n=0; n<len; n++)
{
sio->RxBuf[k] = buf[n];
if (++k >= MAXIOBUF)
k=0;
}
sio->RxEnd = k;
sio->RxNum += n;
if ((sio->RxNum >= sio->FifoSize) && (sio->Ctrl.Control8.Irq & RxIRQ))
{
Irq_Pulse |= sio->IrqLevel;
sio->Status |= SIO_IRQ;
}
sio->Status |= RX_RDY;
}
if ((sio->Ctrl.Control8.Irq & DSRIRQ) &&
(sio->Delta & DSR))
{
sio->Status |= SIO_IRQ;
sio->Delta &= ~DSR;
switch (sio->IrqSrc) {
case SIO_IRQ_IMM:
Irq_Pulse |= sio->IrqLevel;
case SIO_IRQ_NONE:
break;
case SIO_IRQ_ASYNC:
Event_Register |= Event_Mask[sio->IrqLevel] | 0x80000000;
Event_List[sio->IrqLevel] = sio->IrqFlags; // & 0x7FFFFFFF;
break;
case SIO_IRQ_VSYNC:
VSync_Register |= Event_Mask[sio->IrqLevel] | 0x80000000;
Event_List[sio->IrqLevel] = sio->IrqFlags; // & 0x7FFFFFFF;
break;
}
}
return len;
}